using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using XNA = Microsoft.Xna.Framework;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Graphics;
using ImagesMath;
using ImagesMath.Transformations;
using Graphics.Geometries;
using Graphics.Lights;
using Graphics.Films;
using Raytrace;
using Graphics3D;

namespace XNAWinForms
{

    public partial class Form1 : XNAWinForm
    {
        private float mRotation = 0f;
        private Matrix mViewMat, mWorldMat, mProjectionMat;
        private BasicEffect mSimpleEffect;
        private Camera camera;
        private SpotLight light;
        private Graphics.SceneController scene;


        Graphics3D.SceneController XNASceneController;

        private int dimension;
        private int positionX;
        private int positionY;
        private int positionZ;
        private int directionX;
        private int directionY;
        private int directionZ;
        private int angle;
        private int lpositionX;
        private int lpositionY;
        private int lpositionZ;
        private int ldirectionX;
        private int ldirectionY;
        private int ldirectionZ;

        private Graphics.Texture texture;



        VertexPositionColor[] triVerts = new VertexPositionColor[] {
            new VertexPositionColor(Vector3.Zero*2,
                        Microsoft.Xna.Framework.Graphics.Color.Blue),
            new VertexPositionColor(Vector3.Right*2,
                        Microsoft.Xna.Framework.Graphics.Color.Green),
            new VertexPositionColor(Vector3.Up*2,
                        Microsoft.Xna.Framework.Graphics.Color.Red)};


        /// <summary>
        /// 
        /// </summary>
        public Form1()
        {
            InitializeComponent();

            //XNASceneController = new Graphics3D.SceneController(game);

            this.DeviceResetting += new XNAWinForm.EmptyEventHandler(mWinForm_DeviceResetting);
            this.DeviceReset += new XNAWinForm.GraphicsDeviceDelegate(mWinForm_DeviceReset);
            this.OnFrameRender += new XNAWinForm.GraphicsDeviceDelegate(mWinForm_OnFrameRender);
            this.OnFrameMove += new GraphicsDeviceDelegate(Form1_OnFrameMove);

            mViewMat = mWorldMat = mProjectionMat = Matrix.Identity;

            dimension = 128;
            CreateScene();
    
        }

        private void CreateScene()
        {



            bool reflection = this.ReflectionCheckBox.Checked;
            bool transmittion = this.TransmitionCheckBox.Checked;
            directionX = int.Parse(this.DirectionXtextBox.Text);
            directionY = int.Parse(this.DirectionYtextBox.Text);
            directionZ = int.Parse(this.DirectionZtextBox.Text);
            positionX = int.Parse(this.PositionXtextBox.Text);
            positionY = int.Parse(this.PositionYtextBox.Text);
            positionZ = int.Parse(this.PositionZtextBox.Text);
            ldirectionX = int.Parse(this.LDirectionXTextBox.Text);
            ldirectionY = int.Parse(this.LDirectionYTextBox.Text);
            ldirectionZ = int.Parse(this.LDirectionZTextBox.Text);
            lpositionX = int.Parse(this.LPositionXTextBox.Text);
            lpositionY = int.Parse(this.LPositionYTextBox.Text);
            lpositionZ = int.Parse(this.LPositionZTextBox.Text);
            angle = int.Parse(this.LightAngleTextbox.Text);
            int.TryParse(this.DimensionTextBox.Text, out this.dimension);

            camera = new Camera(new PR3(positionX, positionY, positionZ), new PR3(directionX, directionY, directionZ), new VR3(0, 1, 0), 30);
            light = new SpotLight(new PR3(lpositionX, lpositionY, lpositionZ), new VR3(ldirectionX, ldirectionY, ldirectionZ), angle);
            scene = new Graphics.SceneController(dimension, reflection, transmittion);
            scene.SetLight(light);

            scene.SetCamera(camera);


        }
        public void RenderScene()
        {
            RaytraceForm form = new RaytraceForm();
            form.Show();
            scene.Render();
            form.PictureBox.Image = scene.GetRenderImage();
        }
       

        #region Events

        private void ouvrirTextureToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog();
            fd.ShowDialog();
            if (fd.FileName != string.Empty)
            {
                RaytraceForm form = new RaytraceForm();
                texture = new Graphics.Texture(fd.FileName);
                form.PictureBox.Image = texture.GetBitmapImage();
                form.Show();
            }
        }

        private void lancerLeRenduToolStripMenuItem_Click_1(object sender, EventArgs e)
        {

            RenderScene();
        }


        private void lancerLeRenduToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateScene();
        }

        private void DimensionTextBox_TextChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

        private void PositionXtextBox_TextChanged(object sender, EventArgs e)
        {

            CreateScene();
        }

        private void PositionYtextBox_TextChanged(object sender, EventArgs e)
        {

            CreateScene();
        }

        private void PositionZtextBox_TextChanged(object sender, EventArgs e)
        {

            CreateScene();
        }

        private void DirectionXtextBox_TextChanged(object sender, EventArgs e)
        {

            CreateScene();
        }

        private void DirectionYtextBox_TextChanged(object sender, EventArgs e)
        {

            CreateScene();
        }

        private void DirectionZtextBox_TextChanged(object sender, EventArgs e)
        {

            CreateScene();
        }

        private void LPositionXTextBox_TextChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

        private void LPositionYTextBox_TextChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

        private void LPositionZTextBox_TextChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

        private void LDirectionXTextBox_TextChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

        private void LDirectionYTextBox_TextChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

        private void LDirectionZTextBox_TextChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

        private void LightAngleTextbox_TextChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

        #endregion


        /// <summary>
        /// 
        /// </summary>
        /// <param name="pDevice"></param>
        void Form1_OnFrameMove(Microsoft.Xna.Framework.Graphics.GraphicsDevice pDevice)
        {
            mRotation += 0.1f;
            this.mWorldMat = Matrix.CreateRotationY(mRotation);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pDevice"></param>
        void mWinForm_OnFrameRender(GraphicsDevice pDevice)
        {
            // Configure effect
            mSimpleEffect.World = this.mWorldMat;
            mSimpleEffect.View = this.mViewMat;
            mSimpleEffect.Projection = this.mProjectionMat;
            mSimpleEffect.DiffuseColor = XNA.Graphics.Color.DarkRed.ToVector3();
            mSimpleEffect.CommitChanges();


            // Draw
            mSimpleEffect.Begin();
            mSimpleEffect.Techniques[0].Passes[0].Begin();
            pDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList,
                triVerts, 0, 1);
            mSimpleEffect.Techniques[0].Passes[0].End();
            mSimpleEffect.End();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pDevice"></param>
        void mWinForm_DeviceReset(GraphicsDevice pDevice)
        {
            // Re-Create effect
            mSimpleEffect = new BasicEffect(pDevice, null);

            // Configure device
            pDevice.VertexDeclaration = new VertexDeclaration(pDevice, VertexPositionColor.VertexElements);
            pDevice.RenderState.CullMode = CullMode.None;

            // Create camera and projection matrix
            mWorldMat = Matrix.Identity;
            mViewMat = Matrix.CreateLookAt(Vector3.Backward * 10,Vector3.Zero, Vector3.Up);
            mProjectionMat = Matrix.CreatePerspectiveFieldOfView(MathHelper.Pi / 4.0f,
                    (float)pDevice.PresentationParameters.BackBufferWidth / (float)pDevice.PresentationParameters.BackBufferHeight,
                    1.0f, 100.0f);
        }
        /// <summary>
        /// 
        /// </summary>
        void mWinForm_DeviceResetting()
        {
            // Dispose all
            if (mSimpleEffect != null)
                mSimpleEffect.Dispose();
        }

        private void ReflectionCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

        private void TransmitionCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            CreateScene();
        }

       


        
    }
}